package com.pig4cloud.pig.ai.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNode;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pig.admin.api.entity.SysDept;
import com.pig4cloud.pig.ai.api.entity.RelationEntity;
import com.pig4cloud.pig.ai.mapper.RelationMapper;
import com.pig4cloud.pig.ai.service.RelationService;
import lombok.AllArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 图谱表管理
 *
 * @author xuzhuang
 * @date 2024年6月13日15:00:56
 */
@Service
@AllArgsConstructor
public class RelationServiceImpl extends ServiceImpl<RelationMapper, RelationEntity> implements RelationService {

	private final RelationMapper relationMapper;

	/**
	 * 获取知识图谱树形结构数据
	 * @param datasourceName
	 * @return
	 */
	@Override
	public List<Tree<Long>> selectTree(long topoId,String datasourceName) {
		// 查询所有
		List<RelationEntity> deptAllList = relationMapper
				.selectList(Wrappers.<RelationEntity>lambdaQuery()
						.eq(RelationEntity::getTopoId, topoId)
						.like(StrUtil.isNotBlank(datasourceName), RelationEntity::getDatasourceName, datasourceName));

		// 权限
		List<TreeNode<Long>> collect = deptAllList.stream()
				.filter(dept -> dept.getId().intValue() != dept.getRelationId())
				.sorted(Comparator.comparingInt(RelationEntity::getSortOrder))
				.map(dept -> {
					TreeNode<Long> treeNode = new TreeNode();
					treeNode.setId(dept.getId());
					treeNode.setParentId(dept.getRelationId());
					treeNode.setName(dept.getFiledSchema());
					treeNode.setWeight(dept.getSortOrder());
					// 有权限不返回标识
					Map<String, Object> extra = new HashMap<>(8);
					extra.put("createTime", dept.getCreateTime());
					treeNode.setExtra(extra);
					return treeNode;
				})
				.collect(Collectors.toList());

		// 模糊查询 不组装树结构 直接返回 表格方便编辑
		if (StrUtil.isNotBlank(datasourceName)) {
			return collect.stream().map(node -> {
				Tree<Long> tree = new Tree<>();
				tree.putAll(node.getExtra());
				BeanUtils.copyProperties(node, tree);
				return tree;
			}).collect(Collectors.toList());
		}

		return TreeUtil.build(collect, 0L);
	}

	/**
	 * 图谱关系数据
	 * @param topoId
	 * @return
	 */
	@Override
	public List<RelationEntity> selectTreeTopoId(Long topoId) {
		List<RelationEntity> allDeptList = relationMapper.selectList(Wrappers.emptyWrapper());

		// 递归查询所有子节点
		List<RelationEntity> deptAllList = new ArrayList<>();
		recursiveDept(allDeptList, topoId, deptAllList);

		// 添加当前节点
		deptAllList.addAll(allDeptList.stream()
				.filter(relationEntity -> topoId.equals(relationEntity.getId()))
				.collect(Collectors.toList()));
		return deptAllList;
	}

	/**
	 * 删除图谱
	 * @param id 图谱 ID
	 * @return 成功、失败
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public Boolean removeRelationEntityById(Long id) {
		// 级联删除部门
		List<Long> idList = this.listDescendant(id).stream().map(RelationEntity::getId).collect(Collectors.toList());

		Optional.ofNullable(idList).filter(CollUtil::isNotEmpty).ifPresent(this::removeByIds);

		return Boolean.TRUE;
	}


	/**
	 * 查询所有子节点 （包含当前节点）
	 * @param id 部门ID 目标部门ID
	 * @return ID
	 */
	@Override
	public List<RelationEntity> listDescendant(Long id) {
		// 查询全部部门
		List<RelationEntity> allDeptList = baseMapper.selectList(Wrappers.emptyWrapper());

		// 递归查询所有子节点
		List<RelationEntity> resDeptList = new ArrayList<>();
		recursiveDept(allDeptList, id, resDeptList);

		// 添加当前节点
		resDeptList.addAll(allDeptList.stream()
				.filter(sysDept -> id.equals(sysDept.getId()))
				.collect(Collectors.toList()));
		return resDeptList;
	}

	/**
	 * 递归查询所有子节点。
	 * @param allDeptList 所有部门列表
	 * @param relationId 父部门ID
	 * @param resDeptList 结果集合
	 */
	private void recursiveDept(List<RelationEntity> allDeptList, Long relationId, List<RelationEntity> resDeptList) {
		// 使用 Stream API 进行筛选和遍历
		allDeptList.stream().filter(sysDept -> sysDept.getRelationId().equals(relationId)).forEach(sysDept -> {
			resDeptList.add(sysDept);
			recursiveDept(allDeptList, sysDept.getId(), resDeptList);
		});
	}

}